package cn.iocoder.yudao.module.member.vip.service;

import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.dao.repository.SerialNoRedisRepository;
import cn.iocoder.yudao.framework.business.order.service.AppOrderBaseService;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.member.vip.enums.VipTypeEnum;
import cn.iocoder.yudao.module.api.member.vip.vo.VipOrderVO;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillTypeEnum;
import cn.iocoder.yudao.module.api.pay.order.PayOrderApi;
import cn.iocoder.yudao.module.api.pay.order.dto.PayOrderCreateDTO;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.member.vip.dal.dataobject.VipCardDO;
import cn.iocoder.yudao.module.member.vip.dal.dataobject.VipOrderDO;
import cn.iocoder.yudao.module.member.vip.dal.mysql.VipCardMapper;
import cn.iocoder.yudao.module.member.vip.dal.mysql.VipOrderMapper;
import cn.iocoder.yudao.module.member.vip.dto.AppVipOrderSubmitDTO;
import cn.iocoder.yudao.module.member.vip.mq.VipProducer;
import cn.iocoder.yudao.module.member.vip.vo.AppVipOrderVO;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.api.member.ConfigConstants.VIP_CARD_ORDER_NO_PREFIX;
import static cn.iocoder.yudao.module.api.member.ErrorCodeConstants.VIP_CARD_NOT_EXISTS;

/**
 * 会员卡订单 Service 实现类
 *
 * @author 山野羡民
 */
@Slf4j
@Service
@Validated
public class AppVipOrderServiceImpl extends AppOrderBaseService<VipOrderDO, AppVipOrderVO, AppVipOrderSubmitDTO> implements AppVipOrderService {
    @Resource
    private VipOrderMapper vipOrderMapper;
    @Resource
    private VipCardMapper vipCardMapper;

    @Resource
    private AppVipUserService appVipUserService;

    @Resource
    private SerialNoRedisRepository serialNoRedisRepository;
    @Resource
    private VipProducer vipProducer;

    @Resource
    private PayOrderApi payOrderApi;
    @Resource
    private ShopInfoApi shopInfoApi;

    @Override
    protected VipOrderMapper getInjectedMapper() {
        return vipOrderMapper;
    }

    @Nonnull
    @Override
    protected VipOrderDO onOrderCreateBefore(@Nonnull AppVipOrderSubmitDTO reqVO, @Nonnull Long userId) {
        // 校验会员卡存在
        VipCardDO vipCardDO = vipCardMapper.selectById(reqVO.getCardId());
        if (vipCardDO == null) {
            throw exception(VIP_CARD_NOT_EXISTS);
        }
        Integer vipType = vipCardDO.getType();
        if (shopInfoApi.isOwnerByMemberUserId(userId)) {
            Assertions.equals(VipTypeEnum.MERCHANT.getValue(), vipType, "商家只能购买商户类型的会员套餐");
        } else {
            Assertions.equals(VipTypeEnum.MEMBER.getValue(), vipType, "用户不能购买商户类型的会员套餐");
        }
        boolean renewal = appVipUserService.isValid(userId, null);
        // 构建订单信息
        VipOrderDO order = new VipOrderDO();
        order.setUserId(userId);
        order.setType(vipType);
        order.setCardId(vipCardDO.getId());
        order.setFromShopId(NumberUtil.nullToZero(reqVO.getShopId()));
        order.setDays(vipCardDO.getDays());
        order.setPrice(vipCardDO.getPrice());
        order.setGivePoint(vipCardDO.getGivePoint());
        order.setSnapshot(JsonUtils.toJsonString(vipCardDO));
        order.setTradeNo(serialNoRedisRepository.generateNo(VIP_CARD_ORDER_NO_PREFIX));
        order.setNote("购买会员套餐【%s】".formatted(vipCardDO.getName()));
        order.setRenewal(renewal);
        return order;
    }

    @Async
    @Override
    public void createPayOrder(@Nonnull VipOrderDO order) {
        PayOrderCreateDTO createDTO = new PayOrderCreateDTO();
        createDTO.setTradeNo(order.getTradeNo());
        createDTO.setSubject(BillTypeEnum.PAY_VIP.getName());
        createDTO.setBody(order.getNote());
        createDTO.setPrice(order.getPrice());
        String payNo = payOrderApi.createOrder(createDTO);
        // 创建付款单据后再回来更新业务订单的支付单号
        VipOrderDO updateObj = new VipOrderDO();
        updateObj.setId(order.getId());
        updateObj.setPayNo(payNo);
        getInjectedMapper().updateById(updateObj);
    }

    @Override
    protected void onPaidAfter(VipOrderDO order) {
        appVipUserService.updateWhenPaid(order);
        vipProducer.sendVipOrderPaidMessage(BeanUtils.toBean(order, VipOrderVO.class));
    }

    @Override
    public PageResult<AppVipOrderVO> getPage(Integer pageNo, Integer pageSize, Long userId) {
        CoreQueryWrapper<VipOrderDO> wrapper = new CoreQueryWrapper<>();
        wrapper.eq("user_id", userId);
        PageResult<VipOrderDO> page = vipOrderMapper.selectPage(pageNo, pageSize, wrapper);
        return convertToViewObject(page);
    }

}